package com.mobilesales.android.activities.tasks;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SlidingDrawer;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.mobilesales.android.R;
import com.mobilesales.android.activities.IRefreshable;
import com.mobilesales.android.adapters.TaskAdapter;
import com.mobilesales.android.c2dm.C2DMMessaging;
import com.mobilesales.android.c2dm.NotificationReceiver;
import com.mobilesales.android.database.ClientManager;
import com.mobilesales.android.database.TaskManager;
import com.mobilesales.android.infrastructure.IPushpinSelected;
import com.mobilesales.android.infrastructure.MapOverlays;
import com.mobilesales.android.model.clients.Client;
import com.mobilesales.android.model.tasks.CyclicTask;
import com.mobilesales.android.model.tasks.Schedule;
import com.mobilesales.android.model.tasks.Task;
import com.mobilesales.android.util.Constants;
import com.mobilesales.android.util.DateUtil;
import com.mobilesales.android.util.Geolocalization;
import com.mobilesales.android.util.MessageBox;
import com.mobilesales.android.util.Settings;

public class TaskMap extends FragmentActivity implements IPushpinSelected,
		IRefreshable {

	public void refresh() {
		// TODO Auto-generated method stub
		
	}

	public void OnPushpinSelected(GeoPoint gp) {
		// TODO Auto-generated method stub
		
	}
/*
	private static final int INITIAL_ZOOM = 12;

	private static final int CONTEXT_CENTER = 0;
	private static final int CONTEXT_SHOWHIDE = 1;
	private static final int CONTEXT_DETAILS = 2;

	private MapView mapView;
	private MapOverlays itemizedOverlay;
	private MapController mapController;

	private Date selectedDate;
	private List<Task> tasksOfDay;
	private Map<Task, GeoPoint> taskGeopointMap;

	private TaskAdapter itemsAdapter;
	private ListView taskList;
	private SlidingDrawer slidingDrawer;

	private NotificationReceiver receiver;
	private Handler handler = new Handler();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.map);

		this.initTaskList();
		this.initMap();
		receiver = new NotificationReceiver() {
			@Override
			public void onMessage(String msg) {
				refresh();
			}
		};
		C2DMMessaging.addNotificationReceiver(receiver);

		Bundle bundle = this.getIntent().getExtras();
		if (bundle != null && bundle.containsKey(Constants.SelectedDate)) {
			selectedDate = (Date) bundle.get(Constants.SelectedDate);
			Log.i("selectedDate", selectedDate.toLocaleString());
			loadItems();
		} else {
			MessageBox.show(this, getString(R.string.ErrorTaskList));
			finish();
		}
	}

	private void initTaskList() {
		slidingDrawer = (SlidingDrawer) this.findViewById(R.id.slidingDrawer);
		taskList = (ListView) this.findViewById(R.id.taskList);
		taskList.setEmptyView(this.findViewById(R.id.taskListEmpty));
		taskList.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> adpt, View view,
					int position, long id) {
				if (itemsAdapter != null) {
					Task tsk = itemsAdapter.getItem(position);
					showDetails(tsk);
				}
			}
		});
		this.registerForContextMenu(taskList);
	}

	private void initCurrentPosition() {
		if (this.itemizedOverlay != null) {
			Location loc = Geolocalization.getCurrentLocation(this);

			 MOCK! 
			
			 * GeoPoint gp = new GeoPoint((int) (50 * 1E6), (int) (20 * 1E6));
			 * this.itemizedOverlay.setCurrentLocation(gp);
			 

			if (loc != null) {
				GeoPoint gp = new GeoPoint((int) (loc.getLatitude() * 1E6),
						(int) (loc.getLongitude() * 1E6));
				//this.itemizedOverlay.setCurrentLocation(gp);
			} else {
				MessageBox.show(this, getString(R.string.ErrorGeolocalization));
			}

		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		if (v.getId() == R.id.taskList && itemizedOverlay != null) {
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;

			Log.i("contextMenu", "position:" + info.position);
			Task tsk = itemsAdapter.getItem(info.position);
			GeoPoint gp = taskGeopointMap.get(tsk);
			boolean isVisible = itemizedOverlay.getVisibility(gp);

			String[] menuItems = new String[3];
			menuItems[CONTEXT_CENTER] = getString(R.string.Center);
			menuItems[CONTEXT_SHOWHIDE] = isVisible ? getString(R.string.Hide)
					: getString(R.string.Show);
			menuItems[CONTEXT_DETAILS] = getString(R.string.Details);

			for (int i = 0; i < menuItems.length; i++) {
				menu.add(Menu.NONE, i, i, menuItems[i]);
			}
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		Log.i("contextMenu",
				"position:" + info.position + " action:" + item.getItemId());
		Task tsk = itemsAdapter.getItem(info.position);
		GeoPoint gp = taskGeopointMap.get(tsk);

		switch (item.getItemId()) {
		case CONTEXT_CENTER:
			slidingDrawer.animateClose();
			if (itemizedOverlay != null) {
				itemizedOverlay.setCurrentItem(gp);
				itemsAdapter.setActiveTask(tsk);
			}
			this.mapController.animateTo(gp);
			break;
		case CONTEXT_SHOWHIDE:
			if (itemizedOverlay != null) {
				boolean isVisible = itemizedOverlay.getVisibility(gp);
				slidingDrawer.animateClose();
				itemizedOverlay.setVisibility(gp, !isVisible);
				itemsAdapter.setTaskVisibility(tsk, !isVisible);
			}
			break;
		case CONTEXT_DETAILS:
			this.showDetails(tsk);
			break;
		}

		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		if (itemizedOverlay != null) {
			OverlayItem item = itemizedOverlay.getCurrentItem();
			if (item != null
					&& item != itemizedOverlay.getCurrentLocationItem()) {
				MenuInflater inflater = getMenuInflater();
				inflater.inflate(R.menu.map_menu, menu);

				Location loc = Geolocalization.getCurrentLocation(this);
				if (loc == null) {
					menu.getItem(2).setEnabled(false);
				}

				// TODO:remove below
				menu.removeItem(R.id.route);
				// /////

				return true;
			}
		}
		return false;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.route:

			break;
		case R.id.hidee:
			if (itemizedOverlay != null) {
				OverlayItem oItem = itemizedOverlay.getCurrentItem();
				itemizedOverlay.setVisibility(oItem.getPoint(), false);
				Task tsk = this.getTaskFromGeopoint(oItem.getPoint());
				itemsAdapter.setTaskVisibility(tsk, false);
			}
			break;
		case R.id.details:
			if (itemizedOverlay != null) {
				OverlayItem oItem = itemizedOverlay.getCurrentItem();
				Task tsk = this.getTaskFromGeopoint(oItem.getPoint());
				this.showDetails(tsk);
			}
			break;
		}
		return true;
	}

	public void OnPushpinSelected(GeoPoint gp) {
		Task tsk = this.getTaskFromGeopoint(gp);
		if (tsk != null && itemsAdapter != null) {
			this.itemsAdapter.setActiveTask(tsk);
		}
	}

	private void showDetails(Task tsk) {
		boolean isCyclicTask = (tsk instanceof CyclicTask);
		Intent intent = new Intent(this, DetailsTask.class);
		intent.putExtra(Constants.TaskId, tsk.Id);
		intent.putExtra(Constants.IsCyclicTask, isCyclicTask);
		this.startActivityForResult(intent, 0);
	}

	private Task getTaskFromGeopoint(GeoPoint gp) {
		if (taskGeopointMap != null) {
			for (Task tsk : taskGeopointMap.keySet()) {
				if (taskGeopointMap.get(tsk).equals(gp)) {
					return tsk;
				}
			}
		}
		return null;
	}

	private void initMap() {
		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);
		mapController = mapView.getController();
		mapController.setZoom(INITIAL_ZOOM);
	}

	public void addPushpin(String address, String description) {
		Location loc = Geolocalization.reverseGeocode(this, address);
		if (loc != null) {
			GeoPoint gp = new GeoPoint((int) (loc.getLatitude() * 1E6),
					(int) (loc.getLongitude() * 1E6));
			this.addPushpin(gp, description);
		}
	}

	public void addPushpin(GeoPoint gp, String description) {

		if (itemizedOverlay == null) {
			List<Overlay> mapOverlays = mapView.getOverlays();
			Drawable drawable = this.getResources().getDrawable(
					R.drawable.pin_blue);
			itemizedOverlay = new MapOverlays(drawable, this);
			itemizedOverlay.setMapController(mapController);
			itemizedOverlay.setPushpinSelectedListener(this);
			this.initCurrentPosition();
			mapOverlays.add(itemizedOverlay);
		}
		Log.i("addPushpin", gp.getLatitudeE6() + "," + gp.getLongitudeE6());
		OverlayItem overtask = new OverlayItem(gp, description, description);
		itemizedOverlay.addOverlay(overtask);
		mapController.animateTo(gp);
	}

	private void loadItems() {
		tasksOfDay = this.getItems();
		if (tasksOfDay != null) {
			this.setItemsSource(tasksOfDay);
		} else {
			MessageBox.show(this, getString(R.string.ErrorTaskList));
			finish();
		}
	}

	protected void setItemsSource(List<Task> source) {
		List<Task> itemsToDisable = new ArrayList<Task>();
		taskGeopointMap = new HashMap<Task, GeoPoint>();
		boolean success = true;
		for (int i = 0; i < source.size(); i++) {
			boolean disableItem = false;
			Task tsk = source.get(i);

			if (tsk.ClientId != null && tsk.ClientId != 0) {
				Client clnt = this.getClient(tsk.ClientId);
				if (clnt != null) {
					String address = clnt.Street + ", " + clnt.City;
					String desc = clnt.Name + "\n" + clnt.Street + "\n"
							+ clnt.Zipcode + " " + clnt.City;

					Location loc = Geolocalization
							.reverseGeocode(this, address);

					 MOCK! 
					Random rand = new Random();
					int randVal = rand.nextInt(50000) - 25000;
					GeoPoint gp = new GeoPoint((int) (50 * 1E6 + randVal),
							(int) (20 * 1E6 + randVal));
					taskGeopointMap.put(tsk, gp);
					this.addPushpin(gp, desc);

					
					 * if (loc != null) { GeoPoint gp = new GeoPoint((int)
					 * (loc.getLatitude() * 1E6), (int) (loc.getLongitude() *
					 * 1E6));
					 * 
					 * taskGeopointMap.put(tsk, gp); this.addPushpin(gp, desc);
					 * } else { disableItem = true; }
					 

				} else {
					disableItem = true;
					MessageBox.show(this, getString(R.string.ErrorClient));
				}
			} else {
				disableItem = true;
			}

			if (disableItem) {
				itemsToDisable.add(tsk);
			}
			success &= !disableItem;
		}

		itemsAdapter = new TaskAdapter(this, R.layout.task_list_item, source,
				itemsToDisable);
		taskList.setAdapter(itemsAdapter);

		if (!success) {
			MessageBox.show(this, getString(R.string.ErrorTaskOnMap));
			this.slidingDrawer.animateOpen();
		}
	}

	private Client getClient(int clientId) {
		ClientManager manager = new ClientManager(this);
		Client result = manager.GetClient(clientId);
		manager.Close();
		return result;
	}

	protected List<Task> getItems() {
		if (this.selectedDate != null) {
			List<Task> tasks = getTasks(selectedDate);
			List<CyclicTask> cyclicTasks = getCyclicTasks(selectedDate);
			List<Task> tasksOfDay = new ArrayList<Task>();
			if (tasks != null && cyclicTasks != null) {
				for (Task tsk : tasks)
					tasksOfDay.add(tsk);
				for (CyclicTask tsk : cyclicTasks)
					tasksOfDay.add(tsk);
				return tasksOfDay;
			}
		}
		return null;
	}

	private List<CyclicTask> getCyclicTasks(Date currentDate) {
		Log.i("currentDate", currentDate.toLocaleString());
		TaskManager manager = new TaskManager(this);
		List<CyclicTask> tasks = manager.GetCyclicTaskList(Settings
				.getSettings().getEmployeeId());
		manager.Close();

		List<CyclicTask> taskInTime = null;
		if (tasks != null) {
			taskInTime = new ArrayList<CyclicTask>();
			GregorianCalendar calendar = new GregorianCalendar();
			for (CyclicTask tsk : tasks) {
				Date date = DateUtil.parseDate(tsk.StartTime);
				calendar.setTime(date);
				GregorianCalendar current = new GregorianCalendar();
				current.setTime(currentDate);
				current.set(GregorianCalendar.HOUR_OF_DAY,
						calendar.get(GregorianCalendar.HOUR_OF_DAY));
				current.set(GregorianCalendar.MINUTE,
						calendar.get(GregorianCalendar.MINUTE));

				Log.i("Current", current.getTime().toLocaleString());
				Log.i("Day", calendar.getTime().toLocaleString());

				long diff = Math.abs(current.getTimeInMillis()
						- calendar.getTimeInMillis())
						/ (24 * 60 * 60 * 1000);

				Log.i("diff", diff + "");
				Log.i("taskInterval", tsk.TaskInterval + "");
				Log.i("diff % tsk.TaskInterval", (diff % tsk.TaskInterval) + "");

				if (diff % tsk.TaskInterval == 0)
					taskInTime.add(tsk);
			}
			Log.i("MobileSales", "taskInTime:" + taskInTime.size());

		}
		return taskInTime;
	}

	private List<Task> getTasks(Date date) {
		List<Task> tasks = null;
		TaskManager manager = new TaskManager(this);
		List<Schedule> schedules = manager.GetScheduleList(Settings
				.getSettings().getEmployeeId());
		if (schedules != null) {
			tasks = new ArrayList<Task>();
			for (Schedule s : schedules) {
				List<Task> stasks = manager.GetTaskList(s.Id);
				if (stasks != null) {
					tasks.addAll(stasks);
				} else {
					tasks = null;
					break;
				}
			}
		}
		manager.Close();
		if (tasks != null) {
			List<Task> incorrect = new ArrayList<Task>();
			for (Task t : tasks) {
				String currentDate = DateUtil.toShortDateString(date);
				String taskDate = t.StartTime.split(" ")[0];
				if (!currentDate.equals(taskDate)) {
					incorrect.add(t);
				}
			}
			for (Task t : incorrect)
				tasks.remove(t);
		}
		return tasks;
	}

	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (receiver != null)
			C2DMMessaging.removeNotificationReceiver(receiver);
	}

	public void refresh() {
		handler.post(new Runnable() {
			public void run() {
				finish();
			}
		});
	}
*/
}
